﻿using System;
using System.Collections.Generic;
using System.Text;
using NHibernate;
using NHibernate.Cfg;
using System.Web;
using XWG.Framework.AuthSPConst;
using XWG.JWBST;
namespace XWG.JWBST.JWBSTDAL
{
    /// <summary>
    /// 在ASP.NET环境下使用NHibernate的帮助类。
    /// </summary>
    public sealed class Db
    {
        private const string sessionKey = "NHibernate.Db";
        private static readonly NHibernate.Cfg.Configuration configuration = new NHibernate.Cfg.Configuration();
        
        private static readonly ISessionFactory sessionFactory = configuration.Configure(HttpContext.Current.Request.MapPath(System.Configuration.ConfigurationManager.AppSettings["nhibernate.config"])).BuildSessionFactory();
        
         //private static readonly ISessionFactory sessionFactory = (new Configuration()).Configure().BuildSessionFactory();
        
        private Db() { }
        static Db() { }

        #region public static ISession Session
        /// <summary>
        /// 获取一个可用的Session实例。
        /// </summary>
        public static ISession Session
        {
            get
            {
                ISession session;
                if (HttpContext.Current.Items.Contains(sessionKey))
                {
                    session = (ISession)HttpContext.Current.Items[sessionKey];
                }
                else
                {
                    session = Db.sessionFactory.OpenSession();
                    //session = Db.sessionFactory.OpenSession(new MyInterceptor());
                    HttpContext.Current.Items[sessionKey] = session;
                }
                return session;
            }
        }
        #endregion

        #region public static ISessionFactory SessionFactory
        /// <summary>
        /// 获取当前的SessionFactory实例。
        /// </summary>
        public static ISessionFactory SessionFactory
        {
            get { return Db.sessionFactory; }
        }
        #endregion

        #region public static Configuration Configuration
        /// <summary>
        /// 获取当前的Configuration实例。
        /// </summary>
        //public static Configuration Configuration
        //{
        //    get { return Db.configuration; }
        //}
        #endregion

        #region public static void CloseSession()
        /// <summary>
        /// 关闭Session。
        /// </summary>
        /// <remarks>
        /// 应该在EndRequest事件发生时被调用，写在HttpModule中。
        /// </remarks>
        public static void CloseSession()
        {
            if (HttpContext.Current.Items.Contains(sessionKey))
            {
                ISession session = (ISession)HttpContext.Current.Items[sessionKey];
                session.Close();
                HttpContext.Current.Items.Remove(sessionKey);
            }
        }
        #endregion

        #region public static T GetModel(object key)
        /// <summary>
        /// 根据主键获取对象实体
        /// </summary>
        /// <param name="item">主键</param>
        public static T GetModel<T>(object key)where T:class,new()
        {
            
            try
            {
                return Db.Session.Get<T>(key);
            }
            catch(Exception ex)
            {
                throw;
            }
        }

        #endregion

        #region public static IList<T> GetModel(string where)
        /// <summary>
        /// 根据条件获取实体列表 from tablename where ...
        /// </summary>
        /// <param name="item">HSQL</param>
        public static IList<T> GetModel<T>(string where) where T : class,new()
        {

            try
            {
                return Db.Session.CreateQuery(where).List<T>();
            }
            catch
            {
                throw;
            }
        }

        #endregion
        #region 多事务多类型的事务处理

        //public static void TransOP(System.Collections.Hashtable hashtable)
        //{
        //    ITransaction transaction = Db.Session.BeginTransaction();
        //    try
        //    {
        //        System.Collections.IDictionaryEnumerator enumerator = hashtable.GetEnumerator();
        //        while (enumerator.MoveNext())
        //        {
        //            switch ((int)enumerator.Key)
        //            {
        //                case (int)AuthSPConst.OP.Create:
        //                    Db.Session.Save(enumerator.Value);
        //                    break;
        //                case (int)AuthSPConst.OP.Delete:
        //                    Db.Session.Delete(enumerator.Value);
        //                    break;
        //                case (int)AuthSPConst.OP.Update:
        //                    Db.Session.Update(enumerator.Value);
        //                    break;
        //                case (int)AuthSPConst.OP.DeleteBulk:
        //                    {
        //                        XWG.Framework.AuthUtility.DeleteBulkModel mDeleteBulkModel = new AuthUtility.DeleteBulkModel();
                                
        //                        mDeleteBulkModel = (XWG.Framework.AuthUtility.DeleteBulkModel)enumerator.Value;
        //                        List<string> list=mDeleteBulkModel.IDArray;
        //                        string arr="";
        //                        for(int i=0;i<list.Count;i++)
        //                        {
        //                            arr+="'"+list[i]+"',";
        //                        }
        //                        arr=arr.TrimEnd(',');
        //                        DeleteArr(mDeleteBulkModel.TableNameMapping, mDeleteBulkModel.ColumnNameMapping, arr,false,null);
        //                    }
        //                    break;
        //                default:
        //                    break;
        //            }

        //        }

        //        //Db.Session.Save(item);
        //        transaction.Commit();
        //    }
        //    catch
        //    {
        //        transaction.Rollback();
        //        throw;
        //    }

        //}
        //public static void TransOP<T, O>(IList<object> oplist, IList<int> OPEnum)
        //    where T : class, new()
        //    where O : class,new()
        //{
             
        //    ITransaction transaction = Db.Session.BeginTransaction();
        //    try
        //    {

        //        for (int i = 0; i < OPEnum.Count; i++)
        //        {
        //            switch (Convert.ToInt32(OPEnum[i]))
        //            {
        //                case (int)OP.Create:
        //                    Db.Session.Save(oplist[i]);
        //                    break;
        //                case (int)OP.Delete:
        //                    Db.Session.Delete(oplist[i]);
        //                    break;
        //                case (int)OP.Update:
        //                    Db.Session.Update(oplist[i]);
        //                    break;
        //                case (int)OP.DeleteBulk:
        //                    {
        //                        XWG.Framework.AuthUtility.DeleteBulkModel mDeleteBulkModel = new XWG.Framework.AuthUtility.DeleteBulkModel();
        //                        mDeleteBulkModel = (XWG.Framework.AuthUtility.DeleteBulkModel)oplist[i];
        //                        List<string> list = mDeleteBulkModel.IDArray;
        //                        string arr = "";
        //                        for (int j = 0; j < list.Count; j++)
        //                        {
        //                            arr += "'" + list[j] + "',";
        //                        }
        //                        arr = arr.TrimEnd(',');
        //                        DeleteArrNoTran(mDeleteBulkModel.TableNameMapping, mDeleteBulkModel.ColumnNameMapping, arr,mDeleteBulkModel.where, false, null);
        //                    }
        //                    break;
        //                default:
        //                    break;
        //            }
        //        }
        //        //Db.Session.Save(item);
        //        transaction.Commit();
        //    }
        //    catch (Exception ex)
        //    {
        //        transaction.Rollback();
        //        throw;
        //    }

        //}

        /// <summary>
        /// TransOP
        /// </summary>
        /// <typeparam name="T"><peparam>
        /// <typeparam name="O"><peparam>
        /// <param name="IsSucceed">是否成功</param>
        /// <param name="oplist">oplist</param>
        /// <param name="OPEnum">OPEnum</param>
        public static void TransOP<T, O>(ref bool IsSucceed, IList<object> oplist, IList<int> OPEnum)
            where T : class, new()
            where O : class,new()
        {
            IsSucceed = true;
            ITransaction transaction = Db.Session.BeginTransaction();
            try
            {

                for (int i = 0; i < OPEnum.Count; i++)
                {
                    switch (Convert.ToInt32(OPEnum[i]))
                    {
                            
                        case (int)OP.Create:
                            Db.Session.Save(oplist[i]);
                            break;
                        case (int)OP.Delete:
                            Db.Session.Delete(oplist[i]);
                            break;
                        case (int)OP.Update:
                            Db.Session.Update(oplist[i]);
                            break;
                        case (int)OP.DeleteBulk:
                            {
                                XWG.Framework.AuthUtility.DeleteBulkModel mDeleteBulkModel = new XWG.Framework.AuthUtility.DeleteBulkModel();
                                mDeleteBulkModel = (XWG.Framework.AuthUtility.DeleteBulkModel)oplist[i];
                                List<string> list = mDeleteBulkModel.IDArray;
                                string arr = "";
                                for (int j = 0; j < list.Count; j++)
                                {
                                    arr += "'" + list[j] + "',";
                                }
                                arr = arr.TrimEnd(',');
                                DeleteArrNoTran(mDeleteBulkModel.TableNameMapping, mDeleteBulkModel.ColumnNameMapping, arr, mDeleteBulkModel.where, false, null);
                            }
                            break;
                        default:
                            break;
                    }
                }
                //Db.Session.Save(item);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                IsSucceed = false;
                throw;
            }

        }

        /// <summary>
        /// 批量删除。有事务参数
        /// </summary>
        /// <param name="tableNameMapping">所操作的实体类名。</param>
        /// <param name="columnMapping">所操作的属性名。</param>
        /// <param name="idArr">以逗号隔开的主键字符串。</param>
        public static void DeleteArrNoTran(string tableNameMapping, string columnMapping, string idArr, bool isLog, object log)
        {
            ITransaction transaction = null;
            //String hql = "delete " + tablename + " where " + fieldKey + " in ("+idArr+")";
            String hql = "delete from  " + tableNameMapping + "  where " + columnMapping + " in (" + idArr + ")";
            //String hql = "delete from  " + tableNameMapping + "  where " + ColumnMapping + " in ('5dee9c2c-1f0e-4812-af90-d4cc37e78e80','7d982ff3-dee7-4b11-a2f3-b6720db3a9cf')";
            try
            {
                transaction = Db.Session.BeginTransaction();
                IQuery q = Db.Session.CreateQuery(hql);
                //q.SetParameter("a", start);
                q.ExecuteUpdate();
                if (isLog)
                    Db.Session.Save(log);
                
            }
            catch (Exception ex)
            {
                if (transaction != null)
                {
                    transaction.Rollback();
                }
                throw ex;
            }
        }
        /// <summary>
        /// 批量删除。有事务参数
        /// </summary>
        /// <param name="tableNameMapping">所操作的实体类名。</param>
        /// <param name="columnMapping">所操作的属性名。</param>
        /// <param name="idArr">以逗号隔开的主键字符串。</param>
        /// <param name="where">where格式 and 1=1 and 1=2 or (dd=1)</param>
        public static void DeleteArrNoTran(string tableNameMapping, string columnMapping, string idArr,string where, bool isLog, object log)
        {
            ITransaction transaction = null;
           
            String hql = "delete from  " + tableNameMapping + "  where " + columnMapping + " in (" + idArr + ") ";
            if (!string.IsNullOrEmpty(where))
            {
                hql += where ;
            }
          
            try
            {
                transaction = Db.Session.BeginTransaction();
                IQuery q = Db.Session.CreateQuery(hql);
               
                q.ExecuteUpdate();
                if (isLog)
                    Db.Session.Save(log);

            }
            catch (Exception ex)
            {
                if (transaction != null)
                {
                    transaction.Rollback();
                }
                throw ex;
            }
        }
        /// <summary>
        /// 批量删除。
        /// </summary>
        /// <param name="tableNameMapping">所操作的实体类名。</param>
        /// <param name="columnMapping">所操作的属性名。</param>
        /// <param name="idArr">以逗号隔开的主键字符串。</param>
        public static void DeleteArr(string tableNameMapping, string columnMapping, string idArr,bool isLog,object log)
        {
            ITransaction transaction = null;
            //String hql = "delete " + tablename + " where " + fieldKey + " in ("+idArr+")";
            String hql = "delete from  " + tableNameMapping + "  where " + columnMapping + " in (" + idArr + ")"; 
            //String hql = "delete from  " + tableNameMapping + "  where " + ColumnMapping + " in ('5dee9c2c-1f0e-4812-af90-d4cc37e78e80','7d982ff3-dee7-4b11-a2f3-b6720db3a9cf')";
            try
            {
                transaction = Db.Session.BeginTransaction();
                IQuery q = Db.Session.CreateQuery(hql);
                //q.SetParameter("a", start);
                q.ExecuteUpdate();
                if(isLog)
                Db.Session.Save(log);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                if (transaction != null)
                {
                    transaction.Rollback();
                }
                throw ex;
            }
        }
        #endregion
        #region public static void TransInsert(object item)
        /// <summary>
        /// 将指定的实例插入到数据库中。（事务性操作，适用于多任务的同时插入操作）
        /// </summary>
        /// <param name="item">待插入的实例。</param>
        public static void Insert(ITransaction transaction, object item)
        {
            try
            {
                Db.Session.Save(item);
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 将指定的实例插入到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待插入的实例。</param>
        public static object TransInsert(object item)
        {
            ITransaction transaction = Db.Session.BeginTransaction();
            object _returnValue;
            try
            {
               _returnValue= Db.Session.Save(item);
                transaction.Commit();
                return _returnValue;
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 将指定的实例插入到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="itemlist">待插入的实例。</param>
        /// <param name="isLog">是否写入日志。</param>
        /// <param name="log">待插入的实例。</param>
        public static void TransInsert<T,L>(IList<T> itemlist,bool isLog,L log) where T : class, new() where L:class,new()
        {
            ITransaction transaction = Db.Session.BeginTransaction();
          
            try
            {

                //实体保存
                if (itemlist.Count > 0)
                {
                    for (int i = 0; i < itemlist.Count;i++ )
                        Db.Session.Save(itemlist[i]);
                    
                }
                //写入日志
                if(isLog)
                Db.Session.Save(log);
                transaction.Commit();
                 
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw ex;
            }
        }
  
        /// <summary>
        /// 将指定的实例插入到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待插入的实例。</param>
        public static object TransInsert<T>(T item) where T : class, new()
        {
            ITransaction transaction = Db.Session.BeginTransaction();
            object _returnValue;
            try
            {
                 
                //实体保存
                _returnValue = Db.Session.Save(item);
                //写入日志
                transaction.Commit();
                return _returnValue;
            }
            catch(Exception ex)
            {
                transaction.Rollback();
                throw ex;
            }
        }
        /// <summary>
        /// 将指定的实例插入到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item,item">待插入的实例。日志记录</param>
        public static object TransInsert<T,L>(T item,L log) where T : class, new() where L:class
        {
            ITransaction transaction = Db.Session.BeginTransaction();
            object _returnValue;
            try
            {
                //实体保存
                _returnValue = Db.Session.Save(item);
                //写入日志
                Db.Session.Save(log);
                transaction.Commit();
                return _returnValue;
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw ex;
            }
        }
        #endregion
        #region public static void TransUpdate(object item)
        /// <summary>
        /// 将指定的实例插入到数据库中。（事务性操作，适用于多任务的同时插入操作）
        /// </summary>
        /// <param name="item">待插入的实例。</param>
        public static void Update(ITransaction transaction, object item)
        {
            try
            {
                Db.Session.Update(item);
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 将指定的实例更新到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待更新的实例。</param>
        public static void TransUpdate(object item)
        {
            ITransaction transaction = Db.Session.BeginTransaction();
            try
            {
                Db.Session.Update(item);
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 将指定的实例更新到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待更新的实例。</param>
        public static void TransUpdate<T>(T item) where T: class,new()
        {
            ITransaction transaction = Db.Session.BeginTransaction();

            try
            {
                Db.Session.Update(item);
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 将指定的实例更新到数据库中。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item,log">待更新的实例。写入操作日志</param>
        public static void TransUpdate<T,L>(T item,L log) where T: class,new() where L: class
        {
            ITransaction transaction = Db.Session.BeginTransaction();

            try
            {
                Db.Session.Update(item);
                Db.Session.Save(log);
                transaction.Commit();
            }
            catch (Exception ex)
            {
                transaction.Rollback();
                throw;
            }
        }
        #endregion

        #region public static void TransDelete(object item)
        /// <summary>
        /// 将指定的实例删除。（事务性操作，适用于多任务的同时删除操作）
        /// </summary>
        /// <param name="item">待删除的实例。</param>
        public static void Delete(ITransaction transaction, object item)
        {
            try
            {
                Db.Session.Delete(item);
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 在数据库中删除指定的实例。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待删除的实例。</param>
        public static void TransDelete(object item)
        {
            ITransaction transaction = Db.Session.BeginTransaction();

            try
            {
                Db.Session.Delete(item);
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 在数据库中删除指定的实例。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待删除的实例。</param>
        public static void TransDelete<T>(T item) where T:class ,new()
        {
            ITransaction transaction = Db.Session.BeginTransaction();

            try
            {
                 
                Db.Session.Delete(item);
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        /// <summary>
        /// 在数据库中删除指定的实例。（事务性操作，适用于可能包含及联处理的情况。）
        /// </summary>
        /// <param name="item">待删除的实例。</param>
        public static void TransDelete<T,L>(T item,L log) where T:class ,new() where L:class
        {
            ITransaction transaction = Db.Session.BeginTransaction();
            try
            {
                Db.Session.Delete(item);
                Db.Session.Save(log);
                transaction.Commit();
            }
            catch
            {
                transaction.Rollback();
                throw;
            }
        }
        #endregion

    }
}
